package models.games;

import java.io.IOException;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;

import core.User;
import core.database.DataBaseManager;
import core.database.DataBaseParoleManager;

/**
 * Gioco che richiede all'utente di inserire il maggior numero di parole
 * possibili in un tempo fissato. In questa versione a riga di comando il tempo
 * è sostituito con un numero massimo di turni.
 * 
 * @author Stefano
 * 
 */
public class GocceDiParole extends Game {

	// MODDED 03/01/2014 10:05

	private Random random = new Random();
	// private DataBaseParoleManager dbm;
	private String userName;
	private String url = "jdbc:mysql://localhost:3306/m-health"; // di default
																	// se si usa
																	// il
																	// database
																	// m-health
																	// su server
																	// locale e
																	// porta
																	// 3306
	private String password;
	private static Scanner sc = new Scanner(System.in);
	private Set<String> paroleDate = new HashSet<String>();
	private int countWord;
	private int puntiExp = 1000;
	private String firstString;

	/**
	 * Costruttore del gioco. Per prima cosa si può scegliere se personalizzare
	 * l'url (in modo da usare anche un database su un server online) Vanno
	 * inseriti Username e Password usati per la connessione in MySQL
	 * (nell'implementazione definitiva si potrà omettere questo passaggio)
	 * Viene chiesto se si vuole creare un nuovo database(inteso come tabella)
	 * di parole (da usare se si usa un database nuovo). Se non si crea un nuovo
	 * database viene chiesto se si vuole popolare quello già esistente.
	 * 
	 * @param user
	 * @throws SQLException
	 * @throws IOException
	 */
	public GocceDiParole(User user) throws SQLException, IOException {
		super(user);

		// System.out.println("Vuoi impostare un url personalizzato? (default = jdbc:mysql://localhost:3306/m-health)");
		// if(sc.nextLine().equalsIgnoreCase("si")){
		// System.out.print("Inserire Url: ");
		// url = sc.nextLine();
		// }
		// File f = new
		// File("C:\\Users\\Stefano\\Desktop\\AccessoDatabase.txt");
		// if(!f.exists()){
		// System.out.print("Inserire Username: ");
		// userName = sc.nextLine();
		// System.out.println();
		// System.out.print("Iserire Password: ");
		// password = sc.nextLine();
		// }
		// else{
		// BufferedReader br = new BufferedReader(new FileReader(f));
		// userName = br.readLine();
		// password = br.readLine();
		// br.close();
		// }
		DataBaseManager.connectDefaultFile();
		// dbm = new DataBaseParoleManager(url, userName, password);
		// System.out.println("Vuoi creare un nuovo database di parole?");
		// if(sc.nextLine().equalsIgnoreCase("si")){
		// dbm.creaTabellaParoleAmmesse();
		// }
		// else{
		// System.out.println("Vuoi riempire il database presente?");
		// if(sc.nextLine().equalsIgnoreCase("si")){
		// dbm.riempiDatabase(new File("parole.txt"));
		// }
		// }
		randomizeWord();
	}

	/**
	 * Inizializza il gioco permettendo di scegliere all'utente quando iniziare
	 * (utile quando si implementerà un timer). Viene generata la parola
	 * iniziale da randomizeWord. E' presento un ciclo while che ad ogni
	 * iterazione ripropone le prime tre lettere della parola generata. Ad ogni
	 * input dell'utente il metodo veryfyWord controlla se è presente nel
	 * database(score+1) oppure no(segnalazione errore). Ogni volta che si
	 * inserisce una parola corretta questa viene salvata in un HashSet in modo
	 * da gestire ripetizioni dell'utente. Quando si tenta di inserire una
	 * parola già presente viene segnalato e si perde comunque il turno
	 * (contaTurni si incrementa comunque)
	 * 
	 * @param maxTurni
	 * @throws SQLException
	 */
	public void startGame(int maxTurni) throws SQLException {
		int contaTurni = 1;
		System.out.println("WORD BUBBLE RISING");
		System.out
				.println("Verranno proposte tre lettere dalle quali inserire il maggior numero di parole possibili nel tempo messo a disposizione "
						+ "\nPremere INVIO per inizire");
		sc.nextLine();
		// firstString = randomizeWord();
		// randomizeWord();
		String inputString;
		while (contaTurni <= maxTurni) {
			System.out.println("Partita #" + contaTurni);
			System.out.print(firstString.toLowerCase());
			inputString = firstString + (sc.nextLine().trim().toUpperCase());
			System.out.println();
			if (verify(inputString).equals(VerifyResult.CORRETTO)) {
				if (paroleDate.contains(inputString)) {
					System.out.println("Già inserita");
				} else {
					paroleDate.add(inputString);
				}

			} else
				System.out.print("Errore ");
			System.out.println("Score: " + getScore());
			contaTurni++;
		}

		System.out.println("Fine ContaGocce \nPunteggio finale: " + getScore());

	}

	public enum VerifyResult {
		CORRETTO, RIPETIZIONE, ERRATO
	}

	public VerifyResult verify(String inputString) throws SQLException {
		if (paroleDate.contains(inputString))
			return VerifyResult.RIPETIZIONE;
		if (DataBaseParoleManager.verifyWord(inputString)) {
			paroleDate.add(inputString);
			score += inputString.length() * 150; // DA RIVEDERE TODO
			countWord++;
			if (score == puntiExp) {
				incrementLevel();
				puntiExp = puntiExp + puntiExp * level;
			}
			return VerifyResult.CORRETTO;
		}
		return VerifyResult.ERRATO;
	}

	public int getCountWord() {
		return countWord;
	}

	public String getFirstString() {
		return firstString;
	}

	/**
	 * Sceglie con un random una parola del database. E' presente un ciclo while
	 * che esclude le parole che iniziano con lettere straniere o che comunque
	 * renderebbero troppo complicato il gioco. Escluse anche i casi di parole
	 * che cominciano per ict (presenti solo 4 elementi nel database) e ics(solo
	 * uno)
	 * 
	 * @return Stringa composta dalle prime tre lettere della parola trovata.
	 * @throws SQLException
	 */
	private void randomizeWord() throws SQLException {
		String randomWord = "";
		int i = random.nextInt(60000) + 1;
		randomWord = DataBaseParoleManager.searchWord(i).substring(0, 3);
		char in = randomWord.charAt(0);
		while (in == 'x' || in == 'k' || in == 'j' || in == 'y' || in == 'w'
				|| randomWord.equals("zab") || randomWord.equals("zaf")
				|| randomWord.equals("zai")) {
			i = random.nextInt(60000) + 1;
			randomWord = DataBaseParoleManager.searchWord(i);
		}
		// a questo punto si ha la parte iniziale della stringa da proporre
		// all'utente
		DataBaseParoleManager.buildWordSet(randomWord);
		// }
		firstString = randomWord;

	}

	public void semplifyGame() throws SQLException {
		if (firstString.length() == 1)
			return;
		firstString = firstString.substring(0, firstString.length() - 1);

		DataBaseParoleManager.buildWordSet(firstString);
	}

	@Override
	public int getGameKey() {
		return 8;
	}

}
